/*
 * Copyright (C) 2010 TopCoder Inc., All Rights Reserved.
 */
package com.hercules.android.receiver.commands.call;

import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.hercules.android.receiver.Receiver;
import com.hercules.android.receiver.ReceiverUtil;
import com.hercules.android.receiver.commands.XRECommandHandler;
import com.hercules.android.receiver.commands.XRECommandHandlerException;
import com.hercules.android.receiver.commands.call.animate.XREHandlerAnimate;
import com.hercules.android.receiver.entities.XREObject;
import com.hercules.android.receiver.entities.XREView;

/**
 * <p>
 * This command handler class will handle the animate CALL command.
 * </p>
 * 
 * @author TCSASSEMBER
 * @version 1.0
 */
public class XREAnimateCallCommandHandler extends XRECommandHandler {
    /**
     * Represents the mapping from animation type to the corresponding command
     * handler.
     */
    private Map<String, XREHandlerAnimate> animateHandlers;

    /**
     * Create a new <code>XREAnimateCallCommandHandler</code> with the
     * <code>Receiver</code> and the mapping from animation type to the
     * corresponding command handler.
     * 
     * @param receiver
     *            the <code>Receiver</code> instance.
     * @param animateHandlers
     *            the mapping from animation type to the corresponding command
     *            handler.
     * @throws IllegalArgumentException
     *             if arguments is null
     */
    public XREAnimateCallCommandHandler(Receiver receiver, Map<String, XREHandlerAnimate> animateHandlers) {
        super(receiver);
        ReceiverUtil.checkNull("animateHandlers", animateHandlers);
        this.animateHandlers = animateHandlers;
    }

    /**
     * Process the animate CALL command message. It will call the corresponding
     * handler to handle the message based on the animation type.
     * 
     * @param message
     *            the command message to be processed.
     * @throws XRECommandHandlerException
     *             if any other error occurs
     */
    public void processCommand(JSONObject message) throws XRECommandHandlerException {
        try {
            int targetId = message.getInt("targetId");
            XREObject target = receiver.getApplicationData().getElementsXREIdToElement().get(targetId);
            if (!(target instanceof XREView)) {
                throw new XRECommandHandlerException("Can't find the target with targetId [" + targetId + "].");
            }
            JSONArray params = message.getJSONArray("params");
            int animationId = params.getInt(0);
            XREObject animation = receiver.getApplicationData().getElementsXREIdToElement().get(animationId);
            if (animation == null) {
                return;
                //throw new XRECommandHandlerException("Can't find the target animation with animationId [" + animationId
                //        + "].");
            }
            XREHandlerAnimate animateHandler = animateHandlers.get(animation.getKlass());
            if (animateHandler == null) {
                throw new XRECommandHandlerException("The animation type [" + animation.getKlass()
                        + "] can't be recognized.");
            }
            animateHandler.handle((XREView) target, animation, receiver);
        } catch (JSONException e) {
            throw new XRECommandHandlerException("Error occurs when reading from json.", e);
        }
    }
}
